<?php

namespace app\admin\controller;

use aop\AlipayConfig;
use aop\AopCertClient;
use aop\request\AlipayFundTransUniTransferRequest;
use app\admin\model\User;
use app\common\controller\Backend;
use EasyWeChat\Factory;
use think\exception\ValidateException;
use think\facade\Db;

/**
 * 用户余额提现管理
 *
 * @icon fa fa-circle-o
 */
class UserCash extends Backend
{
    
    /**
     * UserCash模型对象
     * @var \app\admin\model\UserCash
     */
    protected $model = null;
    protected $relationSearch = true;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\UserCash;
        $statusList = \app\admin\model\UserCash::fetchStatus();
        $this->view->assign('statusList', $statusList);
        $this->assignconfig('statusList', $statusList);
    }
    
    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */

    /**
     * 查看.
     */
    public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            [$where, $sort, $order, $offset, $limit] = $this->buildparams();
            $total = $this->model
                ->withJoin(['user'])
                ->where($where)
                ->where('user_cash.is_delete', 1)
                ->order($sort, $order)
                ->count();
            $list  = $this->model
                ->withJoin(['user'])
                ->where($where)
                ->where('user_cash.is_delete', 1)
                ->order($sort, $order)
                ->limit($offset, $limit)
                ->select();
//            dump($list->toArray());die;
            $result = ['total' => $total, 'rows' => $list];

            return json($result);
        }

        return $this->view->fetch();
    }

    /**
     * 详情
     */
    public function detail($ids = null)
    {
        $row = $this->model
            ->field('out_trade_no,user_id,amount,fee,status,note,createtime,pay_number,pay_time,pay_money,reason')
            ->find($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $row = $row->toArray();
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            if (!in_array($row[$this->dataLimitField], $adminIds)) {
                $this->error(__('You have no permission'));
            }
        }
        if($row){
            $row['status'] = \app\admin\model\UserCash::fetchStatus($row['status']);
            $row['createtime'] = date('Y-m-d H:i:s', $row['createtime']);
            $row['pay_time'] = $row['pay_time'] ? date('Y-m-d H:i:s', $row['pay_time']) : '';
            $row['user_id'] = User::where('id', $row['user_id'])->value('username');
        }
        $this->view->assign("row", $row);
        return $this->view->fetch();
    }

    /**
     * 审核
     */
    public function examine()
    {
        $ids = $this->request->param('ids');
        $type = $this->request->param('type');
        $this->modelValidate = true;
        if (!$ids) {
            $this->error(__('No Results were found'));
        }
        $row = $this->model->where('id', 'in', $ids)->select();
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $is_check = true;
        foreach ($row as $value){
            if($value['status'] != 1){
                $is_check = false;break;
            }
        }
        if(!$is_check){
            $this->error('有非待审核状态的订单');
        }
        Db::startTrans();
        try {
            $user_money_model = new \app\admin\model\UserMoneyLog();
            $user_model = new User();
            $platform_log_model = new \app\common\model\PlatformLog();
            $update = ['status' => $type, 'examine_time' => time()];
            $platform_log = [];
            foreach ($row as $key=>$value){
                if($type == 2){//通过
                    $user = $user_model->where('id', $value['user_id'])->find();
                    if($user['user_type'] == 1){
                        //微信小程序打款
                        $res = $this->wechatPay($value, $user);
                        if(!isset($res['return_code']) || !isset($res['result_code']) ||  $res['return_code'] != 'SUCCESS' || $res['result_code'] != 'SUCCESS'){
                            Db::rollback();
                            $this->error('提现失败');
                        }
                        $update['pay_number'] = $res['payment_no'];
                        $update['pay_time'] = $res['payment_time'];
                        $update['pay_money'] = $value['amount'];
                        $platform_log = [
                            'user_id' => $value['user_id'],
                            'amount' => $value['amount'],
                            'type' => 5,
                            'log_note' => '用户余额提现',
                            'order_id' => $value['id'],
                            'order_type' => 1,
                            'createtime' => time(),
                        ];
                        $platform_log_model->save($platform_log);
                        $res = $this->model->where('id', $value['id'])->update($update);
                    }else{
                        //支付宝小程序打款
                        $res = $this->alipay($value, $user);
                        if(!empty($res->code) && $res->code==10000) {
                            $update['pay_number'] = $res->order_id;
                            $update['pay_time'] = strtotime($res->trans_date);
                            $update['pay_money'] = $value['amount'];
                            $platform_log = [
                                'user_id' => $value['user_id'],
                                'amount' => $value['amount'],
                                'type' => 5,
                                'log_note' => '用户余额提现',
                                'order_id' => $value['id'],
                                'order_type' => 1,
                                'createtime' => time(),
                            ];
                            $platform_log_model->save($platform_log);
                            $res = $this->model->where('id', $value['id'])->update($update);
                        }else{
                            Db::rollback();
                            $this->error('提现失败');
                        }
                    }
                }else{//拒绝
                    //返还余额 写入余额流水
                    $user_model->where('id', $value['user_id'])->Inc('money', $value['amount'])->update();
                    $user_money_model->save(['user_id' => $value['user_id'], 'money' => $value['amount'], 'type' => 3, 'log_note' => '用户余额提现审核拒绝返还', 'createtime' => time(), 'order_id' => $value['id']]);
                    $res = $this->model->where('id', $value['id'])->update($update);
                }
            }
            $this->success('审核成功！');
            Db::commit();
        } catch (ValidateException $e) {
            Db::rollback();
            $this->error($e->getMessage());
        } catch (\PDOException $e) {
            Db::rollback();
            $this->error($e->getMessage());
        } catch (Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
    }

    //微信小程序付款到零钱
    public function wechatPay($order, $user){
        $config = \think\facade\Config::get('config_wechat.wechat_pay');
        $amount = bcmul(bcsub($order['amount'], $order['fee'], 2), 100, 0);
        $app = Factory::payment($config);
        $result = $app->transfer->toBalance([
            'partner_trade_no' => $order['out_trade_no'], // 商户订单号，需保持唯一性(只能是字母或者数字，不能包含有符号)
            'openid' => $user['openid'],
            'check_name' => 'FORCE_CHECK', // NO_CHECK：不校验真实姓名, FORCE_CHECK：强校验真实姓名
            're_user_name' => $user['truename'], // 如果 check_name 设置为FORCE_CHECK，则必填用户真实姓名
            'amount' => $amount, // 企业付款金额，单位为分
            'desc' => '用户提现', // 企业付款操作说明信息。必填
        ]);
        return $result;
    }

    //支付宝小程序转账到个人余额
    public function alipay($order, $user){
        $amount = bcsub($order['amount'], $order['fee'], 2);
        $root_path = root_path();
        $alipay_config = config("config_alipay.alipay");//正式
//        $alipay_config = config("config_alipay.alipay_test");//沙箱
        $alipayConfig = new AlipayConfig();
        $alipayConfig->setPrivateKey($alipay_config['privateKey']);
        $alipayConfig->setServerUrl($alipay_config['server_url']);
        $alipayConfig->setAppId($alipay_config['app_id']);
        $alipayConfig->setCharset($alipay_config['charset']);
        $alipayConfig->setSignType($alipay_config['sign_type']);
//        $alipayConfig->setEncryptKey("");
        $alipayConfig->setFormat($alipay_config['format']);
        $alipayConfig->setAppCertPath($root_path.$alipay_config['app_public_cert_path']);
        $alipayConfig->setAlipayPublicCertPath($root_path.$alipay_config['alipay_public_cert_path']);
        $alipayConfig->setRootCertPath($root_path.$alipay_config['alipay_root_cert_path']);
        $alipayClient = new AopCertClient($alipayConfig);
        $alipayClient->isCheckAlipayPublicCert = true;
        $request = new AlipayFundTransUniTransferRequest();
        //业务请求参数
        $bizcontent = json_encode(['out_biz_no'=>$order['out_trade_no'] ,'trans_amount'=>$amount,'product_code'=>'TRANS_ACCOUNT_NO_PWD','biz_scene'=>'DIRECT_TRANSFER','order_title'=>'支付宝提现' , 'payee_info' => ['identity' => $user['alipayid'], 'identity_type' => 'ALIPAY_USER_ID', 'name' => $user['truename']]], JSON_UNESCAPED_UNICODE);
        $request->setBizContent($bizcontent);
        $responseResult = $alipayClient->execute($request);
        $responseApiName = str_replace(".","_",$request->getApiMethodName())."_response";
        $response = $responseResult->$responseApiName;
        return $response;
    }

    /**
     * 删除
     */
    public function del($ids = "")
    {
        $row                 = $this->model->get($ids);
        $this->modelValidate = true;
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $this->model->where('id', 'in', $ids)->update(['is_delete' => 2, 'deletetime' => time()]);
        $this->success();
    }

}
